package com.browsesoft.resource;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;

import com.browsesoft.EntityManager;
import com.browsesoft.Server;
import com.browsesoft.Tools;
import com.browsesoft.user.Role;
import com.browsesoft.user.User;

/**
 * 
 */
public class LicensePolicyTool {
	public LicensePolicyTool() {
	}

	/**
	 * 得到资源res对资源resource的所有访问权限
	 */
	public static Collection getRightType(Resource res, Resource resource)
			throws Exception {
		Collection result = new HashSet();
		Collection policies = getAllPolicy();
		Iterator iter = policies.iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			if (item.containsResource(res) && item.containsByResource(resource)) {
				result.addAll(item.getRights());
			}
		}
		return result;
	}

	public static Collection getUserRightType(User user, Resource resource)
			throws Exception {
		Collection result = new HashSet();
		result.addAll(getRightType(user, resource));
		LinkedList link = ((BasicResource) EntityManager.getInstance()
				.getRoot()).getSpecialResByType("role");
		Iterator iter = link.iterator();
		while (iter.hasNext()) {
			Role role = (Role) iter.next();
			LinkedList list = role.getUsers();
			if (list.contains(user)) {
				result.addAll(getRightType(role, resource));
			}
		}
		return result;
	}

	/**
	 * 得到资源
	 * 
	 * @return 资源
	 * @throws Exception
	 */
	public static boolean hasRight(User user, Resource resource, String rights)
			throws Exception {
		if (hasRightResource(user, resource, rights)) {
			return true;
		}
		LinkedList link = ((BasicResource) EntityManager.getInstance()
				.getRoot()).getSpecialResByType("role");
		Iterator iter = link.iterator();
		while (iter.hasNext()) {
			Role role = (Role) iter.next();
			LinkedList list = role.getUsers();
			if (list.contains(user)) {
				if (hasRightResource(role, resource, rights)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 判断是否有权限
	 * 
	 * @param res
	 * @param resource
	 * @param rights
	 * @return
	 * @throws Exception
	 */
	public static boolean hasRightResource(Resource res, Resource resource,
			String rights) throws Exception {
		Collection policies = getAllPolicy();
		Iterator iter = policies.iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			Collection resourceRights = item.getRights();
			if (isContains((LinkedList) resourceRights, rights)) {
				Collection s = item.getResources();
				if (s.contains(res)) {
					Collection b = item.getByResources();
					if (b.contains(resource)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * 
	 * @param contain
	 * @param byContain
	 * @return
	 */
	private static boolean isContains(LinkedList contain, String byContain) {
		LinkedList ls = Tools.stringToLinkedList(byContain);
		Iterator iter = ls.iterator();
		while (iter.hasNext()) {
			Object item = iter.next();
			if (!contain.contains(item)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 得到用户有权访问的某几类资源的权限
	 * 
	 * @param types
	 *            以逗号分割的资源类型
	 * @return 资源列表
	 */
	public static Collection getRights(User user, String types) {
		try {
			// 得到用户有权访问的所有资源
			Collection result = getResource(user);
			// 对于类型串中的每一项
			Collection retain = new LinkedList();
			Iterator iter = Tools.stringToLinkedList(types).iterator();
			while (iter.hasNext()) {
				String item = (String) iter.next();
				// 得到该类型的所有资源
				LinkedList list = EntityManager.getInstance().getObjects(
						"com.browsesoft.resource.Resource", "resourcetype",
						item);
				// 添加到保留项中
				retain.addAll(list);
			}
			// 保留与资源类型相同的部分
			result.retainAll(retain);
			return result;
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	public static Collection getRights(Resource resource) throws Exception {
		Collection result = new HashSet();
		Collection policies = getAllPolicy();
		Iterator iter = policies.iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			Collection s = item.getResources();
			if (s.contains(resource)) {
				result.addAll(item.getByResources());
			}
		}
		return result;
	}

	/**
	 * 用户取得有权访问的所有资源
	 * @param user 用户
	 * @return 用户有权访问的资源
	 * @throws Exception
	 */
	public static Collection getRightsByUser(User user) throws Exception {
		Collection result = new HashSet();
		Collection policies = getAllPolicy();
		Iterator iter = policies.iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			// 如果改策略实体包含改用户并且没有过滤到改用户
			if (item.isContainerUser(user) && !item.isFilter(user)) {
				Collection byresources = item.getByResources();
				result.addAll(byresources);
			}
		}
		return result;
	}

	public static Collection getRemoteRights(Resource resource,
			Collection resources) throws Exception {
		Collection result = new HashSet();
		Collection policies = getAllRemotePolicy();
		Iterator iter = policies.iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			Collection s = item.getRemoteResources(resources);
			if (isContains(s, resource)) {
				result.addAll(item.getRemoteByResources(resources));
			}
		}
		return result;
	}

	private static boolean isContains(Collection s, Resource resource) {
		Iterator iter = s.iterator();
		while (iter.hasNext()) {
			Resource item = (Resource) iter.next();
			String ID = item.getID();
			if (ID.equals(resource.getID())) {
				return true;
			}
		}
		return false;
	}

	public static Collection getRemoteRights(String userName,
			Collection resources) throws Exception {
		Collection result = new HashSet();
		Collection policies = getAllRemotePolicy();
		Iterator iter = policies.iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			Collection s = item.getRemoteResources(resources);
			if (isContains(s, userName)) {
				result.addAll(item.getRemoteByResources(resources));
			}
		}
		return result;
	}

	private static Collection getRights(String userName) throws Exception {
		Collection result = new HashSet();
		Collection policies = getAllPolicy();
		Iterator iter = policies.iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			Collection s = item.getResources();
			if (isContains(s, userName)) {
				result.addAll(item.getByResources());
			}
		}
		return result;
	}

	private static boolean isContains(Collection s, String userName) {
		Iterator iter = s.iterator();
		while (iter.hasNext()) {
			Resource item = (Resource) iter.next();
			if (item instanceof User) {
				Object ename = item.getAttributes().get("ename");
				if (ename.equals(userName)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 得到资源
	 * 
	 * @return 资源
	 * @throws Exception
	 */
	public static Collection getResource(String user) throws Exception {
		Collection rs = LicensePolicyTool.getRights(user);
		LinkedList link = ((BasicResource) EntityManager.getInstance()
				.getRoot()).getSpecialResByType("role");
		Iterator iter = link.iterator();
		while (iter.hasNext()) {
			Role role = (Role) iter.next();
			LinkedList list = role.getUsers();
			if (list.contains(user)) {
				rs.addAll(LicensePolicyTool.getRights(role));
			}
		}
		return rs;
	}

	/**
	 * 得到资源
	 * 
	 * @return 资源
	 * @throws Exception
	 */
	public static Collection getResource(User user) throws Exception {
		Collection rs = LicensePolicyTool.getRightsByUser(user);
		return rs;
	}

	public static Collection getAllPolicy() {
		try {
			EntityManager manager = EntityManager.getInstance();
			Collection result = manager.getObjects(
					"com.browsesoft.resource.LicensePolicyEntity");
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static Collection getAllRemotePolicy() throws Exception {
		return Server.getEntityManagerRMI().getObjects(
				"com.browsesoft.resource.LicensePolicyEntity");
	}

	/**
	 * 得到用户有某种操作权限的所有资源
	 */
	public static Collection getResourcesOfUser(User user, String rightType) {
		// 得到该用户的所有该类型的权限
		Set result = new HashSet();
		result.addAll(getResources(user, rightType));
		// 得到包含该用户的角色的所有权限
		LinkedList link = ((BasicResource) EntityManager.getInstance()
				.getRoot()).getSpecialResByType("role");
		Iterator iter = link.iterator();
		while (iter.hasNext()) {
			Role role = (Role) iter.next();
			LinkedList list = role.getUsers();
			if (list.contains(user)) {
				result.addAll(getResources(role, rightType));
			}
		}
		return result;
	}

	/**
	 * 得到某个资源有某种操作权限的所有资源
	 */
	public static Collection getResources(Resource res, String rightType) {
		Set result = new HashSet();
		// 对每一个策略
		Iterator iter = getAllPolicy().iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			// 如果该授权策略包含该权限类型且该策略的授权资源包含本资源
			if (item.containsResource(res)
					&& item.getRights().contains(rightType)) {
				// 添加该策略的所有被授权资源到结果中
				result.addAll(item.getByResources());
			}
		}
		return result;
	}

	/**
	 * 得到对某个资源有某种权限的所有资源
	 */
	public static Collection getResourcesHasRight(Resource res, String rightType) {
		Set result = new HashSet();
		// 对每一个策略
		Iterator iter = getAllPolicy().iterator();
		while (iter.hasNext()) {
			LicensePolicyEntity item = (LicensePolicyEntity) iter.next();
			// 如果该授权策略包含该权限类型且该策略的被授权资源包含本资源
			if (item.containsByResource(res)
					&& item.getRights().contains(rightType)) {
				// 添加该策略的所有授权资源到结果中
				result.addAll(item.getResources());
			}
		}
		return result;
	}

	/**
	 * 得到对某个资源有某种权限的所有用户
	 */
	public static Collection getUsersHasRight(Resource res, String rightType) {
		Set result = new HashSet();
		// 对于所有对指定资源有某种权限的资源
		Iterator iter = getResourcesHasRight(res, rightType).iterator();
		while (iter.hasNext()) {
			Resource r = (Resource) iter.next();
			// 是用户，直接放
			if (r instanceof User) {
				result.add(r);
			}
			// 是角色，取角色里的所有用户
			if (r instanceof Role) {
				Role role = (Role) r;
				result.addAll(role.getUsers());
			}
		}
		return result;
	}
}